home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / csrc1.arc / CALEND.C < prev    next >
C/C++ Source or Header  |  1989-07-27  |  10KB  |  304 lines

  1. /*
  2.  *                      C A L E N D A R
  3.  *
  4.  * Usage:
  5.  *      calend  MM              If small, it's a month, if large, a year.
  6.  * or
  7.  *      calend  YYYY MM         year/month
  8.  * or
  9.  *      calend  MM YYYY 
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <time.h>
  14. #include <define.h>
  15.  
  16. #define MWIDTH  (7*3 + 3)               /* Bytes to print a month       */
  17. #define WPERMO  6                       /* Max. weeks per month         */
  18. #define LWIDTH  72                      /* Line width                   */
  19. #define MPERLIN (LWIDTH / MWIDTH)       /* Three months per line        */
  20. #define WWIDTH  (LWIDTH / MPERLIN)      /* Bytes in one week            */
  21. #define BUFSIZ  (WPERMO * LWIDTH)       /* Buffer dimension             */
  22.  
  23. char    *weekday = " S  M Tu  W Th  F  S";
  24. char    *monthname[] = {
  25.         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  26.         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  27. };
  28.  
  29. char    buffer[BUFSIZ];
  30.  
  31. main(argc, argv)
  32. int             argc;
  33. char            *argv[];
  34. {
  35.         register int    month;
  36.         register int    year;
  37.  
  38.         register int    arg1val;
  39.         int             arg1len;
  40.         int             arg2val;
  41.         int             tvec[2];
  42.         struct tm       *tm;
  43.  
  44.         time(&tvec[0]);
  45.         tm = localtime(&tvec[0]);
  46.         year = tm->tm_year + 1900;
  47.         month = tm->tm_mon + 1;
  48.  
  49.         if (argc <= 1)
  50.             /*
  51.              * No arguments mean do last, this, and next month
  52.              */
  53.             do3months(year, month);
  54.         else {
  55.             arg1val = atoi(argv[1]);
  56.             arg1len = strlen(argv[1]);
  57.             if (argc == 2) {
  58.                 /*
  59.                  * Only one argument, if small, it's a month.  If
  60.                  * large, it's a year.  Note:
  61.                  *      calend  0082    Year '82
  62.                  *      calend  82      Year 1982
  63.                  */
  64.                 if (arg1len <= 2 && arg1val <= 12)
  65.                     do3months(year, arg1val);
  66.                 else {
  67.                     if (arg1len <= 2 && arg1val > 0 && arg1val <= 99)
  68.                         arg1val += 1900;
  69.                     doyear(arg1val);
  70.                 }
  71.             }
  72.             else {
  73.                 /*
  74.                  * Two arguments, allow 1980 12 or 12 1980
  75.                  */
  76.                 arg2val = atoi(argv[2]);
  77.                 if (arg1len > 2)
  78.                     do3months(arg1val, arg2val);
  79.                 else
  80.                     do3months(arg2val, arg1val);
  81.             }
  82.         }
  83. getchar();
  84. getchar();        
  85. }
  86.  
  87. doyear(year)
  88. int             year;
  89. /*
  90.  * Print a calendar for an entire year.
  91.  */
  92. {
  93.         register int    month;
  94.         register int    windex;         /* Week index                   */
  95.  
  96.         if (year < 1 || year > 9999)
  97.                 usage();
  98.         printf("\n\n\n%35d\n\n", year);
  99.         for (month = 1; month <= 12; month += MPERLIN) {
  100.                 printf("%12s%23s%23s\n", monthname[month-1],
  101.                                 monthname[month], monthname[month+1]);
  102.                 printf("%s   %s   %s\n", weekday, weekday, weekday);
  103.                 calendar(year, month+0, &buffer[(MWIDTH-1)*0], LWIDTH);
  104.                 calendar(year, month+1, &buffer[(MWIDTH-1)*1], LWIDTH);
  105.                 calendar(year, month+2, &buffer[(MWIDTH-1)*2], LWIDTH);
  106.                 for (windex = 0; windex < (WPERMO * LWIDTH); windex += LWIDTH)
  107.                         out(&buffer[windex], LWIDTH);
  108.         }
  109.         printf("\n\n\n");
  110. }
  111.  
  112. domonth(year, month)
  113. int             year;
  114. int             month;
  115. /*
  116.  * Do one specific month -- note: no longer used
  117.  */
  118. {
  119.         register int    windex;
  120.  
  121.         if (year < 1 || year > 9999)
  122.                 usage();
  123.         if (month <= 0 || month > 12)
  124.                 usage();
  125.         printf("%9s%5d\n\n%s\n", monthname[month-1], year, weekday);
  126.         calendar(year, month, buffer, WWIDTH);
  127.         for (windex = 0; windex < (WPERMO * WWIDTH); windex += WWIDTH)
  128.                 out(&buffer[windex], WWIDTH);
  129.         printf("\n\n");
  130. }
  131.  
  132. do3months(thisyear, thismonth)
  133. int             thisyear;
  134. register int    thismonth;
  135. /*
  136.  * Do last month, this month, and next months.  The parameters
  137.  * are guaranteed accurate. (and year will not be less than 2 nor
  138.  * greater than 9998).
  139.  */
  140. {
  141.         register int    windex;         /* Week index                   */
  142.         int             lastmonth;
  143.         int             lastyear;
  144.         int             nextmonth;
  145.         int             nextyear;
  146.  
  147.         lastyear = nextyear = thisyear;
  148.         if ((lastmonth = thismonth - 1) == 0) {
  149.                 lastmonth = 12;
  150.                 lastyear--;
  151.         }
  152.         if ((nextmonth = thismonth + 1) == 13) {
  153.                 nextmonth = 1;
  154.                 nextyear++;
  155.         }
  156.         printf("%9s%5d%18s%5d%18s%5d\n",
  157.                 monthname[lastmonth - 1], lastyear,
  158.                 monthname[thismonth - 1], thisyear,
  159.                 monthname[nextmonth - 1], nextyear);
  160.         printf("%s   %s   %s\n", weekday, weekday, weekday);
  161.         calendar(lastyear, lastmonth, &buffer[(MWIDTH-1)*0], LWIDTH);
  162.         calendar(thisyear, thismonth, &buffer[(MWIDTH-1)*1], LWIDTH);
  163.         calendar(nextyear, nextmonth, &buffer[(MWIDTH-1)*2], LWIDTH);
  164.         for (windex = 0; windex < (WPERMO * LWIDTH); windex += LWIDTH)
  165.                 out(&buffer[windex], LWIDTH);
  166.         printf("\n\n\n");
  167. }
  168.         
  169. out(text, len)
  170. char            *text;
  171. int             len;
  172. /*
  173.  * Clean up and output this line
  174.  */
  175. {
  176.         register char   *firstp;
  177.         register char   *lastp;
  178.  
  179.         lastp = &text[len];
  180.  
  181.         for (firstp = text; firstp < lastp; firstp++) {
  182.                 if (*firstp == EOS)
  183.                         *firstp = ' ';
  184.         }
  185.         while (lastp > text && *--lastp == ' ');
  186.         lastp[1] = EOS;
  187.         printf("%s\n", text);
  188. }
  189.  
  190. usage()
  191. {
  192.         fprintf(stderr, "Calendar parameter error: ");
  193.         fprintf(stderr, "Usage: \"calend month\" or \"calend year month\"\n");
  194.         fprintf(stderr, "Year and month are integers.\n");
  195.         exit(1);
  196. }
  197.  
  198. /*
  199.  * Actually generate a calendar
  200.  */
  201. static char monthdays[] = {
  202.  0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  203. };                                      /* Thirty days hath september   */
  204.                                         /* Except for 1752              */
  205.  
  206. calendar(year, month, outbuf, offset)
  207. int             year;
  208. int             month;
  209. char            *outbuf;                /* Output goes here             */
  210. int             offset;                 /* "Distance" to next month     */
  211. /*
  212.  * Build the calendar for this year/month
  213.  */
  214. {
  215.         register char   *outp;
  216.         register int    dow;            /* Day of week                  */
  217.         register int    day;            /* Day in month                 */
  218.  
  219.         outp = outbuf;
  220.         dow = jan1(year);
  221.         monthdays[2] = 29;              /* Assume leap year             */
  222.         monthdays[9] = 30;              /* Assume no magic              */
  223.         switch((jan1(year + 1) + 7 - dow) % 7) {
  224.  
  225.         case 2:
  226.                 /*
  227.                  * Leap year if jan 1 of next year is two days after
  228.                  * this year's jan 1
  229.                  */
  230.                 break;
  231.  
  232.         case 1:
  233.                 /*
  234.                  * Not a leap year if jan 1 of next year is the next day
  235.                  * after jan 1 of this year.
  236.                  */
  237.                 monthdays[2] = 28;
  238.                 break;
  239.  
  240.         default:
  241.                 /*
  242.                  * Magic year of 1752 when September lost 11 days.
  243.                  */
  244.                 monthdays[9] = 19;
  245.                 break;
  246.         }
  247.         for (day = 1; day < month; day++)
  248.                 dow += monthdays[day];
  249.         dow %= 7;                       /* Weekday of first of month    */
  250.         outp += (dow * 3);              /* Where to start in calendar   */
  251.         for (day = 1; day <= monthdays[month]; day++) {
  252.                 if (day == 3 && monthdays[month] == 19) {
  253.                         /*
  254.                          * It's magic (September 3 became September 14)
  255.                          * And September 1752 really did have 30 days.
  256.                          */
  257.                         day += 11;
  258.                         monthdays[month] += 11;
  259.                 }
  260.                 if (day > 9)
  261.                         *outp = (day / 10) + '0';
  262.                 outp++;
  263.                 *outp++ = (day % 10) + '0';
  264.                 outp++;
  265.                 if (++dow >= 7) {
  266.                         /*
  267.                          * Sunday, rotate to the next line
  268.                          */
  269.                         dow = 0;
  270.                         outp = &outbuf[offset];
  271.                         outbuf = outp;
  272.                 }
  273.         }
  274. }
  275.  
  276.  
  277. jan1(year)
  278. register int    year;
  279. /*
  280.  * Return day that jan 1 falls on for this year.
  281.  */
  282. {
  283.         register int    day;
  284.  
  285.         /*
  286.          * Gregorian calendar:  one extra day per four years.
  287.          */
  288.         day = year + 4 + (year + 3) / 4;
  289.         /*
  290.          * Julian calendar:  Gregorian less three days per 400
  291.          */
  292.         if (year > 1800) {
  293.                 day -= ((year - 1701) / 100);
  294.                 day += ((year - 1601) / 400);
  295.         }
  296.         /*
  297.          * Calendar changeover year (valid in America only).
  298.          */
  299.         if (year > 1752)
  300.                 day += 3;
  301.         return (day % 7);
  302. }
  303.  
  304.